#!python3
import os

import torch
import torchvision.models
from PIL import Image
import matplotlib.pyplot as plt

from torch_Tensor_usage import torch_Tensor_class
from torch_Dataset_usage import torch_Dataset_class
from torch_Transforms_usage import torch_Transforms_class

import torch_Module_Layer_usage
import torch_Module_usage
import argparse_usage


def about_Tensor():
    """
    Tensor 的使用
    """
    tensor_usage = torch_Tensor_class()

    tensor_usage.Tensor_Create_basic()
    tensor_usage.Tensor_Create_more()
    tensor_usage.Tensor_Edit_basic()
    tensor_usage.Tensor_Calc_autograd()


def about_Dataset():
    """
    Dataset的使用
    """
    path = "test_dataset"
    dataset_usage = torch_Dataset_class()
    dataset_usage.read_frompath(path)
    # 功能比较单一，仅仅是读取图片
    # 现在测试两个重写的方法
    n = dataset_usage.__len__()
    for i in range(n):
        name_image = dataset_usage.__getitem__(i)
        print(name_image)


def about_Transforms():
    """
    Transforms的使用
    载入最喜欢的拉克丝至臻皮肤作为处理对象
    """
    image = Image.open("test_dataset/Qu4iN9.jpg")
    transforms_usage = torch_Transforms_class(image)
    transforms_usage.Transforms_basic_edit()


def about_nn_layer():
    """
    有关Module中的层的使用示例
    在torch_Module_Layer_usage.py中有多个类，首先是对其中的nn.layer库的使用效果示例
    通过编辑注释可以运行单个或多个示例
    """
    module_layer_usage = torch_Module_Layer_usage.torch_nn_layer_usage_class()
    """
    1.--------------------这个是线性变换层的使用示例----------------------------
    """
    # module_layer_usage.layer_basic_linear()

    """
    2.--------------------这个是卷积层的使用示例-------------------------------
    """
    # module_layer_usage.layer_basic_Conv2d()

    """
    3.--------------------这个是最大池化层的使用示例-------------------------------
    """
    # module_layer_usage.layer_basic_Pool()


def about_nn_forward():
    """
    该模型只有前向通道
    该示例将只有学习简单模型使用，定义了一个完整的前向通道对图像进行
    张量变换、卷积、池化、激活函数、线性变换
    :return:
    """
    image = Image.open("test_dataset/Qu4iN9.jpg")
    module_function_usage = torch_Module_usage.torch_nn_forward_usage_class()
    # 传入图片，进行卷积、池化等操作
    module_function_usage.forward(image)


def about_nn_backword():
    """
    该模型有前向通道和反向传播
    该示例将学习模型的基本训练方式
    :return:
    """


def about_Model_ResNet34():
    """
    ResNet的预训练模型文件一共有'resnet18'、'resnet34'、'resnet50'、'resnet101'、'resnet152'、
    'resnext50_32x4d'、'resnext101_32x8d'、'wide_resnet50_2'、'wide_resnet101_2'
    文件一共有1.5G大小，可以通过运行ResNet模型学习中的脚本进行下载。
    本示例通过完整建立一个ResNet34模型来学习深度学习的基本框架
    # 注意，改框架不包括训练部分，只有一个完整的前向通道。

    """
    image = Image.open("test_dataset/Qu4iN9.jpg")
    My_ResNet34 = torch_Module_usage.ResNet34()
    result = My_ResNet34.forward(image)
    print(result)


def about_Parse():
    """
    该函数给出了代码运行时候的参数示例
    通过--name <name> 可以让该函数打印出名称
    """
    pargs = argparse_usage.argparse_usage_class()
    # 实际使用时，通过.parse_args() 获取类的所有成员列表
    # args = pargs.parse_args()
    pargs.parser_show()
    # 示例代码比较长，所以把代码写到了类的方法中去


if __name__ == "__main__":
    # about_Dataset()
    # about_Transforms()
    # about_nn_layer()
    # about_nn_forward()
    # about_Model_ResNet34()
    about_Parse() #该代码解注释时，运行 ./main.py -h 可以查看使用示例

    print("\n\n是否可用CUDA？")
    print(torch.cuda.is_available())
    os.environ['CUDA_VISIBLE_DEVICES'] = '0'
    plt.show()
